}
};
+// A set nbackup state makes firebird open a difference file
+// (BackupManager::actualizeState and openDelta, firebird/src/jrd/nbak.cpp).
+// A database we made is never in that state, so refuse it.
+bool databaseHeaderHasBackupState(const OUString& rDatabasePath)
+{
+ OUString sFileURL;
+ if (::osl::FileBase::getFileURLFromSystemPath(rDatabasePath, sFileURL) != ::osl::FileBase::E_None)
+ return false;
+
+ ::osl::File aFile(sFileURL);
+ if (aFile.open(osl_File_OpenFlag_Read) != ::osl::FileBase::E_None)
+ return false;
+
+ // Ods::header_page, firebird/src/jrd/ods.h
+ sal_uInt8 aHeader[44];
+ sal_uInt64 nRead = 0;
+ ::osl::FileBase::RC eRead = aFile.read(aHeader, sizeof(aHeader), nRead);
+ aFile.close();
+
+ if (eRead != ::osl::FileBase::E_None || nRead < sizeof(aHeader))
+ return false;
+
+ // pag_type, Ods::pag_header
+ const sal_uInt8 nPageTypeHeader = 1;
+ if (aHeader[0] != nPageTypeHeader)
+ return false;
+
+ // hdr_flags & hdr_backup_mask, normal state is 0
+ const sal_uInt16 nFlags = aHeader[42] | (aHeader[43] << 8);
+ const sal_uInt16 nBackupStateMask = 0x0C00;
+ return (nFlags & nBackupStateMask) != 0;
+}
+
}
void Connection::construct(const OUString& url, const Sequence< PropertyValue >& info,
SAL_INFO("connectivity.firebird", "Found .fdb instead of .fbk");
bIsFdbStored = true;
loadDatabaseFile(our_sFDBLocation, m_sFirebirdURL);
+ // Decline a database whose header asks firebird to use a
+ // difference file
+ if (databaseHeaderHasBackupState(m_sFirebirdURL))
+ {
+ ::connectivity::SharedResources aResources;
+ const OUString sMessage = aResources.getResourceString(STR_COULD_NOT_LOAD_FILE).replaceFirst(
+ "$filename$", m_sConnectionURL);
+ ::dbtools::throwGenericSQLException(sMessage, *this);
+ }
}
else
{
# at <https://github.com/FirebirdSQL/firebird/pull/6948> "extern/cloop: Missing dependencies of
# compilations on output directories":
$(eval $(call gb_UnpackedTarball_add_patches,firebird,\
+ external/firebird/firebird-nbak-difference-file-access.patch.1 \
external/firebird/firebird.disable-ib-util-not-found.patch.1 \
external/firebird/firebird-Engine12.patch \
external/firebird/firebird-rpath.patch.0 \
--- /dev/null
+Verify difference file path against DatabaseAccess
+
+The difference file opened in openDelta and beginBackup was not verified
+against DatabaseAccess like the other database file paths.
+
+Submitted upstream as https://github.com/FirebirdSQL/firebird/pull/9089
+
+--- firebird/src/jrd/nbak.cpp
++++ firebird/src/jrd/nbak.cpp
+@@ -35,6 +35,7 @@
+ #include "lck.h"
+ #include "cch.h"
+ #include "lck_proto.h"
++#include "jrd_proto.h"
+ #include "pag_proto.h"
+ #include "err_proto.h"
+ #include "cch_proto.h"
+@@ -224,6 +225,14 @@
+ void BackupManager::openDelta(thread_db* tdbb)
+ {
+ fb_assert(!diff_file);
++
++ // Verify difference file path against DatabaseAccess entry of firebird.conf
++ if (!JRD_verify_database_access(diff_name))
++ {
++ ERR_post(Arg::Gds(isc_conf_access_denied) << Arg::Str("difference file") <<
++ Arg::Str(diff_name));
++ }
++
+ diff_file = PIO_open(tdbb, diff_name, diff_name);
+
+ if (database->dbb_flags & (DBB_force_write | DBB_no_fs_cache))
+@@ -283,6 +292,14 @@
+ {
+ // Create file
+ NBAK_TRACE(("Creating difference file %s", diff_name.c_str()));
++
++ // Verify difference file path against DatabaseAccess entry of firebird.conf
++ if (!JRD_verify_database_access(diff_name))
++ {
++ ERR_post(Arg::Gds(isc_conf_access_denied) << Arg::Str("difference file") <<
++ Arg::Str(diff_name));
++ }
++
+ diff_file = PIO_create(tdbb, diff_name, true, false);
+ }
+ catch (const Firebird::Exception&)